/*
 * Copyright (C) 2011 : Gilles Coomans 
 * 
 * This file is part of QuintEssence.
 * QuintEssence is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * QuintEssence is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with QuintEssence.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.exprom.qe;
import haxe.Http;
//import net.exprom.qe.datas.MetaDataModel;
//import net.exprom.qe.MetaModel;
import Type;
/**
 * ...
 * @author Gilles Coomans
 */

class QECore 
{
	static public var version:String = "0.7.2";
	static public var qe:Dynamic = { };
	static public var typeValidator:QETypeValidator = new QETypeValidator();
	
	static public function resolve(path:String, tryExternalLoad:Bool = true):Dynamic
	{
		#if QEC_DEBUG trace("QECore.resolve : " + path); #end
		var splitted:Array<String> = path.split(".");
		var name = splitted.pop();
		var lastSpace = qe;
		var currentSpace = null;
		var spaceOk = true;
		for (sp in splitted)
		{
			currentSpace = Reflect.field(lastSpace, sp);
			if (currentSpace == null)
			{
				spaceOk = false;
				break;
			}
			lastSpace = currentSpace;
		}
		var res = null;
		if (spaceOk)
			res = Reflect.field(lastSpace, name);
		if (res == null)
			if(tryExternalLoad)
				return loadModel(path);
			else
				throw "Error while trying to resolve path : model not found : " + path;
		//trace("Resolve result : " + res);
		return res;
	}
	
	static public function addLayer(path:String, layer:Dynamic):Dynamic
	{
		#if QEC_DEBUG trace("QECore.addLayer : "+path); #end
		var splitted:Array<String> = path.split(".");
		if (splitted.length  == 0)
			throw "Error : Wrong path provided for resolve";
			
		var name:String = splitted.pop();
		var currentSpace = null;
		var lastSpace = qe;
		var namespace:String = "";
		var first = true;
		for (sp in splitted)
		{
			currentSpace = Reflect.field(lastSpace, sp);
			if (first) 
			{
				namespace += sp;
				first = false;
			}
			else
				namespace += "."+sp;
			if (currentSpace == null)
			{
				currentSpace = {};
				Reflect.setField(lastSpace, sp, currentSpace);
			}
			lastSpace = currentSpace;
		}
		Reflect.setField(lastSpace, name , layer );
		return layer;
	}
	
	static public function addModel(path:String, instance:QEStack = null):QEStack
	{
		#if QEC_DEBUG trace("+ QECore.addModel : "+path); #end
		var splitted:Array<String> = path.split(".");
		if (splitted.length  == 0)
			throw "Error : Wrong path provided for resolve";
			
		var name:String = splitted.pop();
		var currentSpace = null;
		var lastSpace = qe;
		var namespace:String = "";
		var first = true;
		for (sp in splitted)
		{
			currentSpace = Reflect.field(lastSpace, sp);
			if (first) 
			{
				namespace += sp;
				first = false;
			}
			else
				namespace += "."+sp;
			if (currentSpace == null)
			{
				currentSpace = {};
				Reflect.setField(lastSpace, sp, currentSpace);
			}
			lastSpace = currentSpace;
		}
		
		if (instance == null)
			instance = new QEStack(namespace, name);
		Reflect.setField(lastSpace, name , instance );
		instance.setNamespace(namespace, name);
		return instance;
	}
	
	static public function loadModel(modelPath:String):QEStack
	{
		#if QEC_DEBUG trace("QECore.loadModel : " + modelPath); #end
		// parser le path : choper localement
		#if js
			var path = "qem/" + StringTools.replace(modelPath, ".", "_") + ".js";
			var script = Http.requestUrl(path);
			//untyped ojs.tools.OScriptLoader.execute(script);
			var DSLScript  = js.Lib.document.createElement("script");
			DSLScript.setAttribute("type", "text/javascript");
			DSLScript.innerHTML = script;  
			js.Lib.document.body.appendChild(DSLScript);
			js.Lib.document.body.removeChild(DSLScript);
			return QECore.resolve(modelPath);
		#else
			
		#end
	}
	
	static public function loadQEMLib(libPath:String, folderPath:String = null):Void
	{
		#if QEC_DEBUG trace("QECore.loadQEMLib : " + libPath); #end
		#if js
			var path = ((folderPath != null)?folderPath:"qemlib")+"/" + libPath;
			var script = Http.requestUrl(path);
			var DSLScript  = js.Lib.document.createElement("script");
			DSLScript.setAttribute("type", "text/javascript");
			DSLScript.innerHTML = script;  
			js.Lib.document.body.appendChild(DSLScript);
			js.Lib.document.body.removeChild(DSLScript);
		#else
			
		#end
	}
}